home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / modex104.zip / UTILS.ASM < prev    next >
Assembly Source File  |  1993-05-14  |  9KB  |  407 lines

  1. ;=======================================================
  2. ;===  UTILS.ASM  - Asm Utilities for QuickBasic/BC7  ===
  3. ;=======================================================
  4.  
  5.     PAGE    255, 132
  6.  
  7.     .MODEL Medium
  8.     .286
  9.  
  10.     ; ==== MACROS ====
  11.  
  12.     ; macros to PUSH and POP multiple registers
  13.  
  14. PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8
  15.     IFNB <R1>
  16.         push    R1                ; Save R1
  17.         PUSHx    R2, R3, R4, R5, R6, R7, R8
  18.     ENDIF
  19. ENDM
  20.  
  21. POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8
  22.     IFNB <R1>
  23.         pop        R1                ; Restore R1
  24.         POPx    R2, R3, R4, R5, R6, R7, R8
  25.     ENDIF
  26. ENDM
  27.  
  28.     ; Macro to Clear a Register to 0
  29.  
  30. CLR MACRO Register
  31.     xor        Register, Register        ; Set Register = 0
  32. ENDM
  33.  
  34.     ; Macros to Decrement Counter & Jump on Condition
  35.  
  36. LOOPx MACRO Register, Destination
  37.     dec        Register                ; Counter--
  38.     jnz        Destination                ; Jump if not 0
  39. ENDM
  40.  
  41. LOOPjz MACRO Register, Destination
  42.     dec        Register                ; Counter--
  43.     jz        Destination                ; Jump if 0
  44. ENDM
  45.  
  46.  
  47.     ; ==== General Constants ====
  48.  
  49.     False    EQU    0
  50.     True    EQU    -1
  51.     nil        EQU 0
  52.  
  53.     b        EQU    BYTE PTR
  54.     w        EQU    WORD PTR
  55.     d        EQU    DWORD PTR
  56.     o        EQU    OFFSET
  57.     f        EQU FAR PTR
  58.     s        EQU    SHORT
  59.     ?x4        EQU <?,?,?,?>
  60.     ?x3        EQU <?,?,?>
  61.  
  62.  
  63. IFDEF FARSTRINGS
  64.  
  65.     EXTRN    stringaddress:far
  66.     EXTRN    stringlength:far
  67.  
  68. ENDIF
  69.  
  70.  
  71.     .Data
  72.  
  73.     EVEN
  74.  
  75. RND_Seed    DW    7397, 29447, 802
  76. RND_Mult    DW    179, 183, 182
  77. RND_ModV    DW    32771, 32779, 32783
  78.  
  79. CR_LF        DB    13, 10            ; the CRLF data
  80.  
  81.     .Code
  82.  
  83. ;=================
  84. ;DOS_PRINT (Text$)
  85. ;=================
  86. ;
  87. ; Prints Text Directly to DOS console w/ CR/LF
  88. ;
  89.  
  90.     PUBLIC    DOS_PRINT
  91.  
  92. DP_Stack    STRUC
  93.                 DW    ?x4    ; DI, SI, DS, BP
  94.                 DD    ?    ; Caller
  95.     DP_Text        DW    ?    ; Address of Text$ Descriptor
  96. DP_Stack    ENDS
  97.  
  98.  
  99. DOS_PRINT     PROC     FAR
  100.  
  101.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  102.     mov        BP, SP                ; Set up Stack Frame
  103.  
  104.     mov     SI, [BP].DP_Text        ; Get Addr of Text$ descriptor
  105.  
  106. IFDEF FARSTRINGS
  107.     push    SI                    ; Push Addr of BC7 Decriptor Ptr
  108.     call    stringaddress        ; Get Address + Len of string!!!
  109.                                 ; DX:AX = Addr  CX = Len
  110.     mov        DS, DX                ; DS = DX = Segment of string
  111.     mov        DX, AX                ; DX = AX = Offset of String
  112. ELSE
  113.     mov     CX, [SI]             ; put its length into CX
  114.     mov     DX, [SI+02]          ; now DS:DX points to the String
  115. ENDIF
  116.  
  117.     jcxz    @No_Print            ; Don't Print if empty
  118.  
  119.     mov        BX, 1                ; 1= DOS Handle for Display
  120.     mov        AH, 40h                ; Write Text Function
  121.     int        21h                    ; Call DOS to do it
  122.  
  123. @No_Print:
  124.     mov        AX, SEG DGROUP        ; Restore DGroup
  125.     mov        DS, AX
  126.  
  127.     mov        DX, o CR_LF            ; Get Addr of CR/LF pair
  128.     mov        CX, 2                ; 2 Characters to Write        
  129.     mov        BX, 1                ; 1= DOS Handle for Display
  130.  
  131.     mov        AH, 40h                ; Write Text Function
  132.     int        21h                    ; Call DOS to do it
  133.  
  134.     cld                            ; Reset Direction Flag        
  135.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  136.     ret        2                    ; Exit & Clean Up Stack
  137.  
  138. DOS_PRINT     ENDP
  139.  
  140.  
  141. ;==================
  142. ;DOS_PRINTS (Text$)
  143. ;==================
  144. ; Print Text$ Directly to DOS console 
  145. ; without a trailing CR/LF
  146. ;
  147.  
  148.     PUBLIC    DOS_PRINTS
  149.  
  150. DOS_PRINTS     PROC     FAR
  151.  
  152.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  153.     mov        BP, SP                ; Set up Stack Frame
  154.  
  155.     mov     SI, [BP].DP_Text    ; Get Addr of Text$ descriptor
  156.  
  157. IFDEF FARSTRINGS
  158.     push    SI                    ; Push Addr of BC7 Decriptor Ptr
  159.     call    stringaddress        ; Get Address + Len of string!!!
  160.                                 ; DX:AX = Addr  CX = Len
  161.     mov        DS, DX                ; DS = DX = Segment of string
  162.     mov        DX, AX                ; DX = AX = Offset of String
  163. ELSE
  164.     mov     CX, [SI]             ; put its length into CX
  165.     mov     DX, [SI+02]          ; now DS:DX points to the String
  166. ENDIF
  167.  
  168.     jcxz    @DPS_Exit            ; Don't Print if empty
  169.  
  170.     mov        BX, 1                ; 1= DOS Handle for Display
  171.     mov        AH, 40h                ; Write Text Function
  172.     int        21h                    ; Call DOS to do it
  173.  
  174. @DPS_Exit:
  175.     cld                            ; Reset Direction Flag        
  176.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  177.     ret        2                    ; Exit & Clean Up Stack
  178.  
  179. DOS_PRINTS     ENDP
  180.  
  181.  
  182. ;======================
  183. ;SET_VIDEO_MODE (Mode%) 
  184. ;======================
  185. ;
  186. ; Sets the Video Mode through the BIOS
  187. ;
  188.  
  189.     PUBLIC    SET_VIDEO_MODE
  190.  
  191. SVM_Stack    STRUC
  192.                 DW    ?x4    ; DI, SI, DS, BP
  193.                 DD    ?    ; Caller
  194.     SVM_Mode    DB    ?,? ; Desired Video Mode
  195. SVM_Stack    ENDS
  196.  
  197.  
  198. SET_VIDEO_MODE    PROC    FAR
  199.  
  200.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  201.     mov        BP, SP                ; Set up Stack Frame
  202.  
  203.     CLR        AH                    ; Function 0
  204.     mov        AL, [BP].SVM_Mode    ; Get Mode #
  205.  
  206.     int        10H                    ; Change Video Modes
  207.  
  208. @SVM_Exit:
  209.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  210.     ret        2                    ; Exit & Clean Up Stack
  211.  
  212. SET_VIDEO_MODE    ENDP
  213.  
  214.  
  215. ;==============
  216. ;SCAN_KEYBOARD%
  217. ;==============
  218. ;
  219. ; Function to scan keyboard for a pressed key
  220. ;
  221.  
  222.     PUBLIC    SCAN_KEYBOARD
  223.  
  224. SCAN_KEYBOARD    PROC    FAR
  225.  
  226.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  227.  
  228.     mov        AH, 01H                ; Function #1
  229.     int        16H                    ; Call Keyboard Driver
  230.     jz        @SK_NO_KEY            ; Exit if Zero flag set
  231.  
  232.     mov        AH,    00H                ; Remove Key from Buffer
  233.     int        16H                    ; Get Keycode in AX
  234.  
  235.     or        AL, AL                ; Low Byte Set (Ascii?)
  236.     jz        @SK_Exit            ; if not, it's a F-Key
  237.  
  238.     CLR        AH                    ; Clear ScanCode if Ascii
  239.     jmp        s @SK_Exit            ; Return Key in AX
  240.  
  241. @SK_NO_KEY:
  242.     CLR        AX                    ; Return Nil (no Keypress)
  243.  
  244. @SK_Exit:
  245.     cld                            ; Reset Direction Flag        
  246.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  247.     ret                            ; Exit & Clean Up Stack
  248.  
  249. SCAN_KEYBOARD    ENDP
  250.  
  251.  
  252. ;====================
  253. ;RANDOM_INT (MaxInt%)
  254. ;====================
  255. ;
  256. ; Returns a pseudo-random number in the range of (0.. MaxInt-1)
  257. ;
  258.  
  259.  
  260.     PUBLIC    RANDOM_INT
  261.  
  262. RI_Stack    STRUC
  263.                 DW    ?    ; BP
  264.                 DD    ?    ; Caller
  265.     RI_MaxVal    DW    ?    ; Maximum Value to Return + 1
  266. RI_Stack    ENDS
  267.  
  268.  
  269. RANDOM_INT    PROC    FAR
  270.  
  271.     push    BP                    ; Preserve Important Registers
  272.     mov        BP, SP                ; Set up Stack Frame
  273.  
  274.        CLR        BX                    ; BX is the data index
  275.     CLR        CX                      ; CX is the accumulator
  276.  
  277. REPT 3
  278.       mov        AX, RND_Seed[BX]    ; load the initial seed
  279.     mul        RND_Mult[BX]        ; multiply it
  280.     div        RND_ModV[BX]        ; and obtain the Mod value
  281.     mov        RND_Seed[BX], DX    ; save that for the next time
  282.  
  283.     add        CX, DX                ; add it into the accumulator
  284.     inc        BX
  285.     inc        BX                  ; point to the next set of values
  286. ENDM
  287.  
  288.     mov        AX, CX                ; AX = Random #
  289.     CLR        DX                    ; DX = 0
  290.     div        [BP].RI_MaxVal        ; DX = DX:AX / MAxVal Remainder
  291.  
  292.     mov        AX, DX
  293.  
  294.     pop        BP                    ; Restore BP
  295.     ret        2                    ; back to BASIC with AX holding the result
  296.  
  297. RANDOM_INT    ENDP
  298.  
  299.  
  300. ;===========
  301. ;INIT_RANDOM
  302. ;===========
  303. ;
  304. ; Scrambles the psuedo-random number sequence
  305. ; (XOR's the seed value with the timer)
  306. ;
  307.  
  308.     PUBLIC    INIT_RANDOM
  309.  
  310. INIT_RANDOM    PROC    FAR
  311.  
  312.     clr        AX                    ; Segment = 0000
  313.     mov        ES, AX
  314.     mov        AX, ES:[046Ch]      ; Get Timer Lo Word
  315.  
  316.     xor        RND_Seed, AX        ; Scramble 1st Seed
  317.  
  318.     ret                            ; Exit & Clean Up Stack
  319.  
  320. INIT_RANDOM    ENDP
  321.  
  322.  
  323. ;====================
  324. ;INT_SQR (X%, Round%)
  325. ;====================
  326. ;
  327. ; Returns the Integer Square Root of (X)
  328. ; Round allows the return value to be rounded to the 
  329. ; nearest integer value by passing 0x80.  Passing 0
  330. ; return the Integer Portion only.  The rounding amound is
  331. ; a number from 0 to 1 multiplied by 256, thus 
  332. ; 0.5 * 0x100 = 0x80!
  333. ;
  334.  
  335. ISQ_Stack    STRUC
  336.                     DW    ?,?    ; BP, DI
  337.                     DD    ?    ; Caller
  338.     ISQ_Round        DW    ?    ; Amount to Round Result * 256
  339.     ISQ_X            DW    ?    ; "X"
  340. ISQ_Stack    ENDS
  341.  
  342.     PUBLIC    INT_SQR
  343.  
  344. INT_SQR        PROC    FAR
  345.  
  346.     PUSHx   BP, DI                ; Save BP
  347.     mov     BP, SP                ; Set up Stack Frame
  348.  
  349.      xor     AX, AX                ; {xor eax,eax}
  350.     xor     DX, DX                ; {xor edx,edx}
  351.     mov     DI, [BP].ISQ_X        ; {mov edi,x}
  352.  
  353.     mov     CX, 16                ; {mov cx, 32}
  354.  
  355. @ISQ_L:
  356.  
  357.     shl     DI, 1                ; {shl edi,1}
  358.     rcl     DX, 1                ; {rcl edx,1}
  359.     shl     DI, 1                ; {shl edi,1}
  360.     rcl     DX, 1                ; {rcl edx,1}
  361.     shl     AX, 1                ; {shl eax,1}
  362.     mov     BX, AX                ; {mov ebx,eax}
  363.     shl     BX, 1                ; {shl ebx,1}
  364.     inc     BX                     ; {inc ebx}
  365.     cmp     DX, BX                ; {cmp edx,ebx}
  366.     jl         @ISQ_S
  367.  
  368.       sub     DX, BX                ; {sub edx,ebx}
  369.     inc     AX                     ; {inc eax}
  370.  
  371. @ISQ_S: 
  372.     loop     @ISQ_L
  373.  
  374.       add     ax, [BP].ISQ_Round    ; {add eax,$00008000}  
  375.                                 ; {*round* result in hi word: ie. +0.5}
  376.     shr     ax, 8                ; {shr eax,16}  {to ax (result)}
  377.  
  378.     POPx    DI, BP                ; Restore Registers    
  379.     ret        4                    ; Exit
  380.  
  381. INT_SQR        ENDP
  382.  
  383.  
  384. ;============
  385. ;TIMER_COUNT&
  386. ;============
  387. ;
  388. ; Returns the current timer value as an integer/long integer
  389. ;
  390.  
  391.  
  392.     PUBLIC  TIMER_COUNT
  393.  
  394. TIMER_COUNT      PROC    FAR
  395.  
  396.     clr        AX                    ; Segment = 0000
  397.     mov        ES, AX                ; use ES to get at data
  398.     mov        AX, ES:[046Ch]      ; Get Timer Lo Word
  399.     mov        DX, ES:[046Eh]        ; Get Timer Hi Word
  400.     ret                            ; Exit & Return value in DX:AX
  401.  
  402. TIMER_COUNT      ENDP
  403.  
  404.  
  405.     END
  406.